﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Collections;

namespace Sasa.QualityTools.CodeAnalysis.Common
{
    [SuppressMessage("Microsoft.Naming", "CA1724")]
    public static class Text
    {
        [SuppressMessage("Microsoft.Naming", "CA1719")]
        public static string Format(string format, params object[] args)
        {
            return String.Format(CultureInfo.CurrentCulture, format, args);
        }

        public static string Format(Exception ex)
        {
            var messages = new List<string>();
            messages.Add(ex.GetType().FullName);
            foreach (var property in ex.GetType().GetProperties().Where(o => o.Name != "InnerException" && o.CanRead))
            {
                messages.AddRange(ConvertValueToStrings(property.Name, property.GetValue(ex, null)));
            }
            if (ex.InnerException != null)
            {
                messages.Add("");
                messages.Add("---- Inner Exception ----");
                messages.Add(Format(ex.InnerException));
            }
            return String.Join(Environment.NewLine, messages);
        }

        private static IEnumerable<string> ConvertValueToStrings(string name, object value)
        {
            var messages = new List<string>();

            if (value is IDictionary)
            {
                var dictionary = (IDictionary)value;
                foreach (var key in dictionary.Keys)
                {
                    messages.Add(Format("{0}[{1}] = {2}", name, key, dictionary[key]).Replace(Environment.NewLine, ""));
                }
            }
            else if (value is ICollection)
            {
                var list = new ArrayList((ICollection)value);
                for (int i = 0; i < list.Count; i++)
                {
                    messages.Add(Format("{0}[{1}] = {2}", name, i, list[i]).Replace(Environment.NewLine, ""));
                }
            }
            else
            {
                messages.Add(Format("{0} = {1}", name, value).Replace(Environment.NewLine, ""));
            }

            return messages;
        }
    }
}
